/**
 * 暂停执行,只能在async修饰的函数中调用
 * @param {number} time 要暂停的时长, 单位是ms
 */
function sleep(time) {
    return new Promise(res => setTimeout(res, time));
}

/**
 * 输出内容到网页
 * @param {string} str 要输出的内容
 * @param {boolean} isAppend 是否追加,true就是追加不清除原始内容
 */
function write1(str, isAppend = false) {
    var log = document.querySelector('#log')
    if (!log) {
        log = document.createElement('div');
        log.setAttribute('id', 'log');
        document.body.appendChild(log)
    }
    if (isAppend) {
        str = log.innerHTML + '<br>' + str;
    }
    log.innerHTML = str;
}
// 记载外部js文件
async function loadScript(src, timeout = 100000) {
    return new Promise((resovle, reject) => {

        const res = document.createElement('script');
        res.src = src;
        let isBacked = false; // 是否已经回调了
        let t = setTimeout(() => {
            isBacked = true;
            reject();
        }, timeout)
        res.onload = () => {
            if (isBacked) {
                return;
            }
            // 已经加载成功 不需要再监听超时处理
            clearTimeout(t);
            resovle();
        };
        document.head.append(res);
    });
}
var _ = {
    $(selector) {
        return document.querySelector(selector)
    },
    create(tag, props = {}, style = {}) {
        var ele = document.createElement(tag);
        Object.keys(props).forEach(key => {
            ele.setAttribute(key, props[key]);
        })
        Object.keys(style).forEach(key => {
            ele.style[key] = style[key];
        })
        return ele
    }
}
class Music {
    /**
     * 
     * @param {string} url 音乐文件路径
     * @param {boolean} autoPlay 是否自动播放
     * @param {boolean} loop 是否循环
     */
    constructor(url, autoPlay = true, loop = false) {
        this.audio = _.$('#audio');
        if (!this.audio) {
            this.audio = _.create('audio', { id: 'audio' });
            _.$('body').appendChild(this.audio);
        }
        if (url) {
            this.audio.setAttribute('src', url);
        }
        if (loop) {
            this.audio.setAttribute('loop', 'loop');
        } else {
            this.audio.removeAttribute('loop');
        }
        if (autoPlay) {
            this.audio.setAttribute('autoplay', 'autoplay');
            this.audio.play();
        }
        this.audio.volume = 0.02;
    }
    play() {
        this.audio.play();
    }
    pause() {
        this.audio.pause();
    }
    setVolume(v) {
        if (v < 0 || v > 1) { return; }
        this.audio.volume = v;
    }
}

function playMusicOnce(url, volume =1) {
    var audio = _.create('audio');
    document.body.append(audio);
    audio.onended = function(){
        // document.body.removeChild(audio);
    }
    audio.setAttribute('src', url);
    audio.setAttribute('autoplay', 'autoplay');
    // this.audio.play();
    audio.volume = volume;
}
const MAIN_DIV = _.$('#game')
var index = 10;

function DrawBackgroundImage(url, resize = 1) {
    var img = _.$('#main-bg');
    var style = {};
    if (resize) {
        style['transform'] = 'scale(' + resize + ')'
    }
    if (!img) {

        img = _.create('img', { id: 'main-bg' }, {
            position: 'absolute',
            left: 0,
            right: 0,
            top: 0,
            bottom: 0,
            'z-index': 1,
            ...style,
        })
    } else {
        Object.keys(style).forEach(key => {
            img.style[key] = style[key];
        })
    }
    img.src = url
    MAIN_DIV.appendChild(img);
    return {
        delete() { MAIN_DIV.removeChild(img); },
        // 缩放倍数
        resize(n, time = 1000) {
            img.style['transition'] = 'all ' + time + 'ms';
            img.style['transform'] = 'scale(' + n + ')';
            return new Promise(res => setTimeout(res, time));
        }
    }
}
/**
 * 画普通图片
 *
 * @param {*} url
 * @param {number} [x=0]
 * @param {number} [y=0]
 * @param {number} [width=null]
 * @param {number} [height=null]
 * @param {Function} [click] 点击图片的回调函数
 * @returns
 */
function DrawImage(url, x = 0, y = 0, width = null, height = null,click= null) {
    let _style = {
        position: 'absolute',
        left: x + 'px',
        top: y + 'px',
        'z-index': index++
    };
    if (width) _style['width'] = width;
    if (height) _style['height'] = height;
    var img = _.create('img', {}, _style);
    img.src = url
    MAIN_DIV.appendChild(img);
    if(click){
        img.onclick = click
    }
    return {
        // 删除
        delete() { img.parentNode.removeChild(img); },
        //显示在最顶部
        setTop() {
            img.style.zIndex = index++;
        },
        // 缩放倍数
        resize(n, time = 1000) {
            img.style['transition'] = 'all ' + time + 'ms';
            img.style['transform'] = 'scale(' + n + ')';
            return new Promise(res => setTimeout(res, time));
        },
        // 移动图片
        moveTo(x, y) {
            img.style.left = x + 'px';
            img.style.top = y + 'px';
        },
        gray(){
            img.style.filter = 'grayscale(100%)';
            img.style.opacity = '0.8'
        },
        noGray(){
            img.style.filter = '';
            img.style.opacity = '1'
        }
    }
}
var MUSIC = null;
/**
 *播放音乐
 *
 * @param {*} url 为空表示 播放已经暂停的音乐
 * @param {*} auto
 * @param {*} loop
 * @returns
 */
function playMusic(url = null, auto = true, loop = true) {
    if (!url) {
        MUSIC && MUSIC.play()
        return;
    }
    MUSIC = new Music(url, auto, loop);
    auto && MUSIC.play();
    return MUSIC;
}
function setVolume(v) {
    MUSIC && MUSIC.setVolume(v)
}
/**
 * 暂停播放音乐
 *
 */
function stopMusic() {
    MUSIC.pause();
}
/**
 *写内容到网页中
 *
 * @param {*} str
 * @param {*} isAppend
 */
function write(str, isAppend, isClick = false) {
    if (!_.$('#textLog')) {
        _.$('#game').appendChild(_.create('div', { id: 'textLog' }));
    }
    if (_.$('#textLog').style.display == 'none') {
        _.$('#textLog').style.display = 'block'
    }
    _.$('#textLog').style.opacity = 1;
    var text = _.create('div', { class: 'log-item' });
    if (!isAppend) {
        _.$('#textLog').innerHTML = '';
    }
    if (isClick) {
        if (!_.$('#log-pointer')) {
            str += '<img src="img/pointer.svg" id="log-pointer" />';
        }
    }
    text.innerHTML = str;
    _.$('#textLog').appendChild(text);
    setTimeout(() => { text.style.opacity = 1; }, 100);
    if (isClick) {
        _.$('#log-pointer').style.display = 'block';
        // text.style['cursor'] = 'poninter';
        text.classList.add('cursor')
        return new Promise((res, rej) => {
            _.$('#textLog').onclick = () => {
                _.$('#log-pointer').style.display = 'none';
                text.onclick = function () { };
                res({
                    delete() {
                        text.parentNode.removeChild(text);
                    },
                    append(str){
                        text.innerHTML += str;
                    }
                });
            }
        })
    }
    return {
        delete() {
            text.parentNode.removeChild(text);
        },
        append(str){
            text.innerHTML += str;
        }
    }

}
/**
 * 隐藏文字
 *
 */
function hideText() {
    _.$('#textLog').style.opacity = 0;
    setTimeout(() => _.$('#textLog').style.display = 'none', 500)
}
async function startGame() {
    if (typeof (window['main']) != "function") {
        return;
    }
    main();
}
function refresh(showLog = false) {
    _.$('#game').innerHTML = '<div id="textLog" style="' + (showLog ? 'opacity:1;' : '') + '"></div>';
    _.$('#textLog').style.display = 'none';
}
/**
 *
 *
 * @param {String} html 要展示的html代码
 * @param {Number} x 
 * @param {Number} y
 * @param {Function} [click=null]
 * @param {Object} [style={}]
 * @returns
 */
function writeHTML(html, x, y, click = null, style = {}) {
    var div = _.create('div', style, {
        position: 'absolute',
        left: x + 'px',
        top: y + 'px',
        'z-index': index++
    });
    _.$('#game').appendChild(div);
    div.innerHTML = html;
    if (click && typeof (click) == "function") {
        div.onclick = click;
    }
    return {
        delete() {
            div.parentNode.removeChild(div);
        },
        hide() {
            div.style.display = 'none';
        },
        show() {
            div.style.display = '';
        }
    }
}
